import {
	Input,
	Select,
	DatePicker,
	Checkbox,
	InputNumber,
	Radio,
	Switch,
	TreeSelect,
	Upload,
	Button,
	message,
	Image,
} from "antd";
import type { FormItem } from "../Index";
import type { CheckboxOptionType, UploadFile, UploadProps } from "antd";
import type { DefaultOptionType } from "antd/es/select";
import { useState } from "react";
import userStore from "@/store/userStore";
import { PlusOutlined, UploadOutlined } from "@ant-design/icons";
import type { FileType } from "../Index";
type CheckboxOption = string[] | number[] | Array<CheckboxOptionType>;

const { TextArea } = Input;
const { RangePicker } = DatePicker;
/**
 * 要引入value这个属性不然值不会回填上去
 */

/**
 * 表单项输入框
 * @param props
 * @returns
 */
export const FromInput = ({ ...props }: FormItem) => {
	return props?.inputType === "textarea" ? (
		<TextArea
			disabled={props?.disabled}
			allowClear={props?.allowClear ?? true}
			placeholder={props?.placeholder ?? `请输入${props?.label}`}
			onChange={props?.onChange}
			value={props?.value}
		/>
	) : (
		<Input
			disabled={props?.disabled}
			allowClear={props?.allowClear ?? true}
			placeholder={props?.placeholder ?? `请输入${props?.label}`}
			onChange={props?.onChange}
			value={props?.value}
		/>
	);
};

/**
 * 表单项选择器
 * @param props
 * @returns
 */
export const FromSelect = ({ ...props }: FormItem) => {
	return (
		<Select
			disabled={props?.disabled}
			options={props?.options as DefaultOptionType[]}
			onChange={props?.onChange}
			allowClear={props?.allowClear ?? true}
			placeholder={props?.placeholder ?? `请选择${props?.label}`}
			value={props?.value}
		/>
	);
};

/**
 * 表单项日期选择器
 * @param props
 * @returns
 */
export const FromDatePicker = ({ ...props }: FormItem) => {
	return props?.isDateRange ? (
		<RangePicker
			className="w-full"
			picker={props?.picker}
			format={props?.format}
			showTime={props?.showTime}
			onChange={props?.onChange}
			disabled={props?.disabled}
			value={props?.value}
			allowClear={props?.allowClear ?? true}
		/>
	) : (
		<DatePicker
			className="w-full"
			picker={props?.picker}
			format={props?.format}
			showTime={props?.showTime}
			onChange={props?.onChange}
			disabled={props?.disabled}
			value={props?.value}
			allowClear={props?.allowClear ?? true}
		/>
	);
};

/**
 * 表单项复选框
 * @param props
 * @returns
 */
export const FromCheckbox = ({ ...props }: FormItem) => {
	return (
		<Checkbox.Group
			className="w-full"
			disabled={props?.disabled}
			value={props?.value}
			onChange={props?.onChange}
			options={props?.options as CheckboxOptionType[]}
		/>
	);
};

/**
 * 表单项输入框
 * @param props
 * @returns
 */
export const FromInputNumber = ({ ...props }: FormItem) => {
	return (
		<InputNumber
			style={{ width: "100%" }}
			disabled={props?.disabled}
			min={props?.min}
			max={props?.max}
			value={props?.value}
			onChange={props?.onChange}
		/>
	);
};

/**
 * 表单项单选框
 * @param props
 * @returns
 */
export const FromRadio = ({ ...props }: FormItem) => {
	return (
		<Radio.Group
			options={props?.options as CheckboxOption}
			onChange={props?.onChange}
			disabled={props?.disabled}
			value={props?.value}
		/>
	);
};

/**
 * 表单项开关
 * @param props
 * @returns
 */
export const FromSwitch = ({ ...props }: FormItem) => {
	return <Switch disabled={props?.disabled} onChange={props?.onChange} value={props?.value} />;
};

/**
 * 表单项树选择器
 * @param props
 * @returns
 */
export const FromTreeSelect = ({ ...props }: FormItem) => {
	return (
		<TreeSelect
			style={{ width: "100%" }}
			disabled={props?.disabled}
			onChange={props?.onChange}
			value={props?.value}
			treeCheckable={props?.treeCheckable}
			treeData={props?.treeData}
		/>
	);
};

/**
 * 表单项上传
 * @param props
 * @returns
 */
export const FromUpload = ({ ...props }: FormItem) => {
	const token = userStore.getState().userToken?.accessToken || "";
	const [previewOpen, setPreviewOpen] = useState(false);
	const [previewImage, setPreviewImage] = useState<string | undefined>(undefined);

	// 预览
	const handlePreview = async (file: UploadFile) => {
		if (!file.url && !file.preview) {
			file.preview = await getBase64(file.originFileObj as FileType);
		}
		setPreviewImage(file.url || file.preview);
		setPreviewOpen(true);
	};
	// 上传
	const propsFile: UploadProps = {
		beforeUpload: (file) => {
			const maxFileSize = props?.maxFileSize;
			const fileType = props?.fileType;
			// 上传之前校验文件大小
			if (maxFileSize) {
				const fileSize = file.size / 1024 / 1024 < maxFileSize;
				if (!fileSize) {
					message.error(`文件大小不能超过${maxFileSize}MB`);
					return fileSize || Upload.LIST_IGNORE;
				}
			}
			// 上传之前校验文件类型
			if (fileType) {
				console.log(file.type);
				const isFileType = fileType.includes(file.type);
				if (!isFileType) {
					message.error(`文件类型只支持${fileType.join(",")}`);
					return isFileType || Upload.LIST_IGNORE;
				}
			}
		},
		action: props?.action ?? "https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload",
		onChange: props?.onChange,
		headers: {
			token,
		},
		disabled: props?.disabled,
		showUploadList: props?.showUploadList,
		onPreview: props?.previewImage ? handlePreview : undefined,
		defaultFileList: props?.defaultFileList,
		listType: props?.listType,
		fileList: props?.fileList,
		maxCount: props?.maxCount,
	};

	const uploadText = props?.uploadText ?? "上传文件";

	// 获取base64
	const getBase64 = (file: FileType): Promise<string> =>
		new Promise((resolve, reject) => {
			const reader = new FileReader();
			reader.readAsDataURL(file);
			reader.onload = () => resolve(reader.result as string);
			reader.onerror = (error) => reject(error);
		});

	// 上传按钮
	const uploadButton =
		props?.listType === "picture-card" ? (
			<button style={{ border: 0, background: "none" }} type="button">
				<PlusOutlined />
				<div style={{ marginTop: 8 }}>{uploadText}</div>
			</button>
		) : (
			<Button icon={<UploadOutlined />}>{uploadText}</Button>
		);

	// 是否显示上传按钮
	const isShowUploadBtn =
		propsFile.maxCount && propsFile?.fileList ? propsFile?.fileList?.length < propsFile.maxCount : true;

	return (
		<div>
			<Upload {...propsFile}>
				{isShowUploadBtn ? (props?.uplaodBtnRender ? props?.uplaodBtnRender() : uploadButton) : null}
			</Upload>
			{props?.previewImage && (
				<Image
					wrapperStyle={{ display: "none" }}
					preview={{
						visible: previewOpen,
						onVisibleChange: (visible) => setPreviewOpen(visible),
						afterOpenChange: (visible) => !visible && setPreviewImage(""),
					}}
					src={previewImage}
				/>
			)}
		</div>
	);
};
